/*******************************************************************************
 * 版权：北京润尼尔网络科技有限公司，保留所有版权<br>
 * 版本：v1.0.0<br>
 * 文件：AppContext.js<br>
 * 日期：2017年9月29日<br>
 * 作者: 样顺强<br>
 * 功能：应用程序入口对象<br>
 * 
 * 修改记录：<br>
 * 日期 描述 更新功能<br>
 ******************************************************************************/
 
window.makeNamespace(window,"Rainier.UI.V2");

Rainier.UI.V2.AppContext = Rainier.Basic.CompositeObject.extend({

 	NAME : "Rainier.UI.V2.Application",

 	/**
	* 函数名称：init<br>
	* 函数功能：构造函数<br>
	* 参数信息：application:功能函数，
	* 异常信息：无<br>
	*/
 	init : function(application){
 		this._super();
 		this.$container  = null;
 		this.activeEditor= null;
 		this.application = application;
 		this.partLib     = "project";
 		this.experConverter = new Rainier.UI.V2.ExperimentConverter();
		this.webSocket	    = new Rainier.UI.V2.AppWebSocket();
 		this.listeners      = new draw2d.util.ArrayList();
		this.listeners.push(new Rainier.UI.V2.EditorObjectSelectionChangeListener());
		this.listeners.push(new Rainier.UI.V2.PartLibSelectionChangeListener());

		this.currentExperimentName = "";
		
 		//添加事件监听机制，处理返回计算引擎返回信息；
 		window.addEventListener('message', $.proxy(this.messageHandler,this)); 
 	},

	/**
	* 函数名称：connectComputePlugin<br>
	* 函数功能：连接计算引擎插件<br>
	* 参数信息：无，
	* 返回信息：无，
	* 异常信息：无<br>
	*/ 	
 	connectComputePlugin : function(){
 		//启动websocket连接
		if(this.webSocket){
			this.webSocket.connect();
			//定时检测(10s)是否断线 并添加重连功能。
			setInterval($.proxy(function(){
				if(this.webSocket.getReadyState() !== 1){
					this.webSocket.reconnect();
				}
			},this),10000);
		}
 		

 		//初始化信息处理器
 		this.webSocket.getMessageFactory().initMessage();
 	},

 	/**
	* 函数名称：getApplication<br>
	* 函数功能：获取应用对象<br>
	* 参数信息：无，
	* 返回信息：应用程序，
	* 异常信息：无<br>
	*/
 	getApplication : function(){
 		return this.application;
 	},

 	/**
	* 函数名称：getActiveEditor<br>
	* 函数功能：设置应用程序编辑界面<br>
	* 参数信息：activeEditor : 获取当前编辑界面，
	* 返回信息：无，
	* 异常信息：无<br>
	*/
 	setActiveEditor : function(activeEditor){
 		this.activeEditor = activeEditor;
 	},

 	/**
	* 函数名称：getActiveEditor<br>
	* 函数功能：获取应用程序编辑界面<br>
	* 参数信息：无，
	* 返回信息：当前编辑器，
	* 异常信息：无<br>
	*/
 	getActiveEditor : function(){
 		return this.activeEditor;
 	},
    
 	/**
	* 函数名称：setPartLib<br>
	* 函数功能：设置应用程序编辑界面<br>
	* 参数信息：partLib : 设置当前，
	* 异常信息：无<br>
	*/
 	setPartLib : function(partLib){
 		this.partLib = partLib;
 	},

 	/**
	* 函数名称：getPartLib<br>
	* 函数功能：设置应用程序编辑界面<br>
	* 参数信息：无，
	* 返回信息：当前选中的实验，
	* 异常信息：无<br>
	*/
 	getPartLib : function(){
 		return this.partLib;
 	},

 	/**
	* 函数名称：getWebSocket<br>
	* 函数功能：获取socket连接<br>
	* 参数信息：无，
	* 返回信息：当前选中的实验，
	* 异常信息：无<br>
	*/
 	getWebSocket : function(){
 		return this.webSocket;
 	},

 	/**
	* 函数名称：getEditorObjectSelectionChangeListener<br>
	* 函数功能：获取editor面板元件选中变化监听器<br>
	* 参数信息：无，
	* 返回信息：编辑器界面选中元件监听器，
	* 异常信息：无<br>
	*/
 	getEditorObjectSelectionChangeListener : function(){
 		return this.listeners.get(0);
 	},

 	/**
	* 函数名称：getPartLibSelectionChangeListener<br>
	* 函数功能：获取元件库选中改变监听器<br>
	* 参数信息：无，
	* 返回信息：partLib界面选中元件监听器，
	* 异常信息：无<br>
	*/
 	getPartLibSelectionChangeListener : function(){
 		return this.listeners.get(1);
 	},

 	/**
	* 函数名称：getCurrentExperimentName<br>
	* 函数功能：获取实验凭条当前名字<br>
	* 参数信息：无，
	* 返回信息：partLib界面选中元件监听器，
	* 异常信息：无<br>
	*/
 	getCurrentExperimentName : function(){
 		return this.currentExperimentName;
 	},

 	/**
	* 函数名称：setCurrentExperimentName<br>
	* 函数功能：设置实验平台当前实验名字<br>
	* 参数信息：无，
	* 返回信息：partLib界面选中元件监听器，
	* 异常信息：无<br>
	*/
 	setCurrentExperimentName : function(expName){
 		this.currentExperimentName = expName;
 	},

 	/**
	* 函数名称：commandToCopy<br>
	* 函数功能：复制元件<br>
	* 参数信息：无，
	* 返回信息：无，
	* 异常信息：无<br>
	*/
 	commandToCopy : function(){
 		//暂不做处理
       console.log("copy");
 	},

 	/**
	* 函数名称：commandToCut<br>
	* 函数功能：剪切元件<br>
	* 参数信息：无，
	* 返回信息：无，
	* 异常信息：无<br>
	*/
 	commandToCut : function(){
 		//暂不做处理
       console.log("cut");
 	},

 	/**
	* 函数名称：commandToPaste<br>
	* 函数功能：粘贴元件<br>
	* 参数信息：无，
	* 返回信息：无，
	* 异常信息：无<br>
	*/
 	commandToPaste : function(){
 		//暂不做处理
       console.log("paste");
 	},

 	/**
	* 函数名称：commandTodelete<br>
	* 函数功能：删除元件<br>
	* 参数信息：无，
	* 返回信息：无，
	* 异常信息：无<br>
	*/
 	commandToDelete : function(){
 		var activeEditor = this.getActiveEditor();
 		var rootEditPart = activeEditor.rootEditPart;
 		var canvas       = rootEditPart.figure;
		var figures      = canvas.getSelection().all;
		canvas.getCommandStack().startTransaction(draw2d.Configuration.i18n.command.deleteShape);
		figures.each(function(index, figure){
           var cmd = figure.createCommand(new draw2d.command.CommandType(draw2d.command.CommandType.DELETE));
           if(cmd!==null){
        	   canvas.getCommandStack().execute(cmd);
           }
        });
        // execute all single commands at once.
		canvas.getCommandStack().commitTransaction();
 	},

 	/**
	* 函数名称：commandToRedo<br>
	* 函数功能：恢复撤销的内容<br>
	* 参数信息：无，
	* 返回信息：无，
	* 异常信息：无<br>
	*/
 	commandToRedo : function(){
 		var activeEditor = this.getActiveEditor();
 		var rootEditPart = activeEditor.rootEditPart;
 		var canvas       = rootEditPart.figure;
 		canvas.getCommandStack().redo();
 	},

 	/**
	* 函数名称：commandToUndo<br>
	* 函数功能：撤销上一步操作<br>
	* 参数信息：无，
	* 返回信息：无，
	* 异常信息：无<br>
	*/
 	commandToUndo : function(){
 		var activeEditor = this.getActiveEditor();
 		var rootEditPart = activeEditor.rootEditPart;
 		var canvas       = rootEditPart.figure;
 		canvas.getCommandStack().undo();
 	},

 	/**
	* 函数名称：commandToSave<br>
	* 函数功能：保存实验<br>
	* 参数信息：无，
	* 返回信息：无，
	* 异常信息：无<br>
	*/
 	commandToSave : function(){
        var json = this.getActiveEditor().doSave();
        var jsonString = JSON.stringify(json,null,4);
        var random     = (new Date()).getTime();
		var name       = this.currentExperimentName ? this.currentExperimentName : "design_" + random;
        var file = new File([jsonString], name+".ocj", {type: "text/plain;charset=utf-8"});
        saveAs(file);
 	},

 	/**
	* 函数名称：commandToSaveAs<br>
	* 函数功能：另存为实验<br>
	* 参数信息：无，
	* 返回信息：无，
	* 异常信息：无<br>
	*/
 	commandToSaveAs : function(){
 		var random     = (new Date()).getTime();
 		var name = this.currentExperimentName ? this.currentExperimentName : "design_" + random;
      	new Rainier.UI.V2.SaveAsExperimentDialog(name);
 	},

 	/**
	* 函数名称：commandToOpen<br>
	* 函数功能：打开新实验<br>
	* 参数信息：无，
	* 返回信息：无，
	* 异常信息：无<br>
	*/
 	commandToOpen : function(){
       new Rainier.UI.V2.OpenExprimentDialog();
 	},

 	/**
	* 函数名称：commandToFullScreen<br>
	* 函数功能：实验平台全屏显示<br>
	* 参数信息：无，
	* 返回信息：无，
	* 异常信息：无<br>
	*/
 	commandToFullScreen : function(){
 	    var $fullScreen = $("#full_screen");
        var $fullScreenTitle = $fullScreen.attr("title");
        if($fullScreenTitle == "全屏"){
             $fullScreen.children("a").removeClass("fullScreenImg");
             $fullScreen.children("a").addClass("leaveFullScreenImg");
             $fullScreen.attr("title","退出全屏");
             this.enterFullScreen();
        }
        if($fullScreenTitle == "退出全屏"){
            $fullScreen.children("a").addClass("fullScreenImg");
            $fullScreen.children("a").removeClass("leaveFullScreenImg");
            $fullScreen.attr("title","全屏");
            this.exitFullScreen();
        }	
 	},
    
    /**
    * 函数名称：enterFullScreen<br>
    * 函数功能：实验平台全屏显示<br>
    * 参数信息：无，
    * 返回信息：无，
    * 异常信息：无<br>
    */
    enterFullScreen : function(){
        var element = $("body")[0];
        var requestMethod = element.requestFullScreen 
        || element.webkitRequestFullScreen 
        || element.mozRequestFullScreen 
        || element.msRequestFullScreen;
        if (requestMethod) {  
            requestMethod.call(element);
        }
   },
   /**
    * 函数名称：exitFullScreen<br>
    * 函数功能：实验平台退出全屏<br>
    * 参数信息：无，
    * 返回信息：无，
    * 异常信息：无<br>
    */
    exitFullScreen : function(){
        var el = document;
        var cfs = el.cancelFullScreen || el.webkitCancelFullScreen ||
            el.mozCancelFullScreen || el.exitFullScreen;
        if(typeof cfs != "undefined" && cfs) {
            cfs.call(el);
        } else if(typeof window.ActiveXObject != "undefined") {
            //for IE，这里和fullScreen相同，模拟按下F11键退出全屏
        var wscript = new ActiveXObject("WScript.Shell");
        if(wscript != null) {
            wscript.SendKeys("{F11}");
        }
        }
    },
 	/**
	* 函数名称：init<br>
	* 函数功能：恢复原实验平台大小<br>
	* 参数信息：无，
	* 返回信息：无，
	* 异常信息：无<br>
	*/
 	commandToFitScreen : function(){
 		if (document.exitFullscreen) {
            document.exitFullscreen();
        }else if(document.msExitFullscreen) {
            document.msExitFullscreen();
        }else if(document.mozCancelFullScreen) {
            document.mozCancelFullScreen();
        }else if(document.oRequestFullscreen){
            document.oCancelFullScreen();
        }else if(document.webkitExitFullscreen){
            document.webkitExitFullscreen();
        }
 	},

 	//界面运行逻辑
 	/**
	* 函数名称：clickToControlExperiment<br>
	* 函数功能：点击控制实验列表状态<br>
	* 参数信息：无，
	* 返回信息：无，
	* 异常信息：无<br>
	*/
 	clickToControlExperiment : function(){

 	},

 	/**
	* 函数名称：clickToControlPartLib<br>
	* 函数功能：点击控制元件库状态<br>
	* 参数信息：无，
	* 返回信息：无，
	* 异常信息：无<br>
	*/
 	clickToControlPartLib : function(flag){
 		var partLibComponent = this.application.getPartLibComponent();
 		if(flag){
 			partLibComponent.clickToShow();
 		}else{
 			partLibComponent.clickToHide();
 		}
 	},

 	/**
	* 函数名称：clickToControlAnalyse<br>
	* 函数功能：点击控制实验仿真类型<br>
	* 参数信息：无，
	* 返回信息：无，
	* 异常信息：无<br>
	*/
 	clickToControlAnalyse : function(flag){
 		new Rainier.UI.V2.InteractiveAnalysisDialog();
 	},
 	/**
    * 函数名称：clickToControlResult<br>
    * 函数功能：点击控制实验结果类型<br>
    * 参数信息：无，
    * 返回信息：无，
    * 异常信息：无<br>
    */
    clickToControlResult : function(flag){
        var expermentalResult = this.application.getResultComponent();
        if(flag){
            expermentalResult.clickToShow();
        }else{
            expermentalResult.clickTohide();
        }
	},
	
	/**
    * 函数名称：clickToControlResult<br>
    * 函数功能：点击控制实验结果类型<br>
    * 参数信息：无，
    * 返回信息：无，
    * 异常信息：无<br>
    */
   	clickToControlDetectionDialog : function(flag){
		var detectionDialog = this.application.getDetectionComponent();
		if(flag){
			detectionDialog.clickToShow();
		}else{
			detectionDialog.clickTohide();
		}
	},

 	/**
	* 函数名称：clickToControlRunState<br>
	* 函数功能：点击控制当前实验运行状态<br>
	* 参数信息：无，
	* 返回信息：无，
	* 异常信息：无<br>
	*/
 	clickToControlRunState : function(){
 		console.log("运行实验");
 		//关闭当前平台打开的对话框；
 		var dialogs = this.application.dialogList ? this.application.dialogList : null;
 		if(dialogs && dialogs.getSize()){
 			while(dialogs.getSize()>0){
 				dialogs.get(0).dialog.close();
 			}
 		}
		var editor    = this.getActiveEditor();
		var webSocket = this.getWebSocket();
		if(editor && (editor instanceof Rainier.UI.V2.Draw2dGraphicalEditor)){
			var context = editor.context;
			var parser  = context.getCircuitParser();
			if(parser){
				parser.parse(true);
				//第一步：生成spice语句
				// if(context.experimentCfg){						
				// 	sSpice = parser.makeSpice(parser.getSpice());
				// }else{						
				// 	sSpice = parser.addControlSpice(parser.getSpice());
				// }

				if(webSocket){
					//应对 专家评审时，开一个结算引擎，电路和通信之间进行切换bug
					var msgInfoPause = {needReturn:1,type:USER_CMD_MSG,msg:USER_CMD_MSG_PAUSE,engineId:'octave'};
                	var msgInfoStop  = {needReturn:1,type:USER_CMD_MSG,msg:USER_CMD_MSG_STOP,engineId:'octave'};//ngspice
                	webSocket.sendMsgByInfo(msgInfoPause);
                	webSocket.sendMsgByInfo(msgInfoStop);

					var msgInfoScene = {needReturn:1,type:USER_SCENE_MSG,msg:parser.getSpice(),engineId:'octave'};
					var msgInfoRun	 = {needReturn:1,type:USER_CMD_MSG,msg:USER_CMD_MSG_RUN,engineId:'octave'};
					webSocket.sendMsgByInfo(msgInfoScene);
					webSocket.sendMsgByInfo(msgInfoRun);
					
					//保存运行态编辑器到context
					//editor.enterRunStatus();
					editor.rootEditPart.exitCreateState();
					
					if(webSocket){
						var messageHandlerList = webSocket.getMessageFactory().messageHandlerList;
						var messageHandler     = messageHandlerList[CMS_ENGIN_RESULT];
						if(messageHandler){
							var rootModel = editor.context.getRootModel();
							messageHandler.addPropertyListener('propertyListener',rootModel);
						}
					}
				}                                          
			}                                              
		}                                                                     
 	},

 	/**
	* 函数名称：clickToControlRunState<br>
	* 函数功能：点击控制当前实验运行状态<br>
	* 参数信息：无，
	* 返回信息：无，
	* 异常信息：无<br>
	*/
 	clickToControlPauseState : function(){
 		console.log("暂停实验");

		var socket = this.getWebSocket();
		var editor = this.getActiveEditor();
		if(socket){
			var msgInfoPause = {needReturn:1,type:USER_CMD_MSG,msg:USER_CMD_MSG_PAUSE};
			socket.sendMsgByInfo(msgInfoPause);
			
			//退出运行状态；	
			editor.leaveRunStatus();
			
			var messageHandlerList = socket.getMessageFactory().messageHandlerList;
			var messageHandler     = messageHandlerList[CMS_ENGIN_RESULT];
			if(messageHandler){
				messageHandler.clearPropertyListener();
			}
		}
 	},

 	/**
	* 函数名称：clickToControlRunState<br>
	* 函数功能：点击控制当前实验运行状态<br>
	* 参数信息：无，
	* 返回信息：无，
	* 异常信息：无<br>
	*/
 	clickToControlstopState : function(){
 		console.log("停止实验");
		var socket = this.getWebSocket();
		var editor = this.getActiveEditor();
		if(socket && editor){			
			var msgInfoPause = {needReturn:1,type:USER_CMD_MSG,msg:USER_CMD_MSG_PAUSE};
			var msgInfoStop	 = {needReturn:1,type:USER_CMD_MSG,msg:USER_CMD_MSG_STOP};
			socket.sendMsgByInfo(msgInfoPause);
			socket.sendMsgByInfo(msgInfoStop);
			
			//退出运行状态
			editor.leaveRunStatus();
			
			var messageHandlerList = socket.getMessageFactory().messageHandlerList;
			var messageHandler     = messageHandlerList[CMS_ENGIN_RESULT];
			if(messageHandler){
				messageHandler.clearPropertyListener();
			}
		}
 	},
 	
 	/**
    * 函数名称：clickToAnalyticalResults<br>
    * 函数功能：点击控制实验变量状态<br>
    * 参数信息：无，
    * 返回信息：无，
    * 异常信息：无<br>
    */
   clickToAnalyticalResults : function(flag){ 
		var expermentalResult = this.application.getResultComponent();
		expermentalResult.clear();
        expermentalResult.clickTohide();
   },
	/**
	* 函数名称：runExperiment<br>
	* 函数功能：手动启动实验<br>
	* 参数信息：无，
	* 返回信息：无，
	* 异常信息：无<br>
	*/ 	
 	runExperiment : function(){
 		$(".app-run").click();
 	},

 	/**
	* 函数名称：controlAnalyse<br>
	* 函数功能：控制仿真分析的状态<br>
	* 参数信息：无，
	* 返回信息：无，
	* 异常信息：无<br>
	*/
 	controlAnalyse : function(){
 		$(".app-analyse").click();
 	},

 	/**
	 * 函数名称：<br>
	 * 函数功能：<br>
	 * 参数输入：<br>
	 * 参数输出：<br>
	 * 函数返回：<br>
	 * 异常信息：<br>
	 */
	uploadExperiment : function(){
		var activeEditor = this.activeEditor || null;
		if(activeEditor){
			var exper   = activeEditor.doSave();			
			var xmlString = this.experConverter.convertExperToXml(exper);
			return xmlString;
		}
		return '';
	},


 	/**
	* 函数名称：messageHandler<br>
	* 函数功能：处理websocket返回数据<br>
	* 参数信息：无，
	* 返回信息：无，
	* 异常信息：无<br>
	*/
 	messageHandler : function(event){
 		//父页面请求保存当前实验
		if(event.data === 'uploadExperiment'){
			var json = this.uploadExperiment();
			parent.postMessage(json,'*');
		}
		//父页面请求打开实验
		else if(event.data.indexOf('<intellcorrect>') >= 0){
			var scriptVal = event.data;
			if(scriptVal){

				var xmlDoc; //XMLDocument
				var experObject;
	        	xmlDoc = $.parseXML(scriptVal);
	        	if(xmlDoc){
	        		var experString = decodeURIComponent(escape(window.atob($(xmlDoc).find('exper').text())));
	        		experObject = JSON.parse(experString);
					var editor = this.activeEditor;
					if(editor){
						editor.doRestore(experObject);
					}
	        	}				
			}
		}
 	},
 	
 	
    /**
    * 函数名称：setTextValue<br>
    * 函数功能：程序界面数据的存储<br>
    * 参数信息：无，
    * 返回信息：无，
    * 异常信息：无<br>
    */
   setAceTextValue : function(aceTextValue){
       this.aceTextValue =  aceTextValue; 
   },
   /**
    * 函数名称：getTextValue<br>
    * 函数功能：获取程序界面数据的存储<br>
    * 参数信息：无，
    * 返回信息：无，
    * 异常信息：无<br>
    */
   getAceTextValue : function(){
       return this.aceTextValue;
   }
});